// Shader: 外发光
const renderEngine = cc.renderer.renderEngine;
const renderer = renderEngine.renderer;

var shader = {
    name: "geoGlowing",

    params: [
        { name: 'iTime', type: renderer.PARAM_FLOAT, defaultValue: 0.0 },
        { name: 'iResolution', type: renderer.PARAM_FLOAT3 },
        { name: 'iGlowingColor', type: renderer.PARAM_FLOAT4, defaultValue: { x: 1.0, y: 1.0, z: 1.0, w: 1.0 } },
        { name: 'iRadius', type: renderer.PARAM_INT, defaultValue: 4 },
    ],

    defines: [],

    start(sprite, material) {
        this._updateResolution(sprite, material);
    },

    update(sprite, material, dt) {
        //
        this._updateResolution(sprite, material);
        //
        material.setParamValue('iTime', dt);
    },

    _updateResolution(sprite, material) {
        var tex = sprite.spriteFrame.getTexture();
        var newResolution = new cc.Vec3(tex.width, tex.height, 0);
        var oldResolution = material.getParamValue('iResolution');

        if (newResolution.equals(oldResolution) == false){
            material.setParamValue('iResolution', newResolution);
        }
    },

    vert: `uniform mat4 viewProj;
        attribute vec3 a_position;
        attribute vec2 a_uv0;
        varying vec2 uv0;
        void main () {
            vec4 pos = viewProj * vec4(a_position, 1);
            gl_Position = pos;
            uv0 = a_uv0;
        }
        `,

    frag: `uniform sampler2D texture;
    uniform vec3 iResolution;
    uniform float iTime;
    uniform vec4 iGlowingColor;
    uniform int iRadius;
    uniform vec4 color;
    varying vec2 uv0;

    const int MAX_LOOP = 100;

    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        vec2 uv = fragCoord.xy;
        vec2 unit = 1.0 / iResolution.xy;
        vec4 texel = texture2D(texture, uv) * color;
        vec4 finalColor = vec4(0.0);
        float density = 0.0;

        if(texel.a >= iGlowingColor.a)
        {
            finalColor = texel;
        }
        else
        {
            vec2 offset = vec2(0.0);

            for (int i = 0; i < MAX_LOOP; ++i)
            {
                density += texture2D(texture, vec2(uv.x + offset.x, uv.y + offset.y)).a;
                density += texture2D(texture, vec2(uv.x + offset.x, uv.y - offset.y)).a;
                density += texture2D(texture, vec2(uv.x - offset.x, uv.y + offset.y)).a;
                density += texture2D(texture, vec2(uv.x - offset.x, uv.y - offset.y)).a;

                if (i >= iRadius)
                    break;
                    
                offset += unit;
            }
            density /= float(iRadius);
            finalColor = vec4(iGlowingColor.rgb, density);
            finalColor += vec4(texel.rgb * texel.a, texel.a);
        }
        fragColor = finalColor;
    }

    void main()
    {
        mainImage(gl_FragColor, uv0.xy);
    }`,
}

let CustomMaterial = require('CustomMaterial');
CustomMaterial.addShader(shader);